package com.rybbaby.tss.core.utils;

import java.io.UnsupportedEncodingException;
import java.security.interfaces.RSAPrivateKey;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.lang.BooleanUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;

/**
 * @author 谢进伟
 * @description 工程资源文件读取工具
 * @createDate 2016-1-27 下午2:38:36
 */
public class PropertiesReadUtil extends PropertyPlaceholderConfigurer {

    private static Logger log = Logger.getLogger(PropertiesReadUtil.class);
    private static Map<String, String> propertiesMap;
    private final String encoding = "UTF-8";

    /**
     * 读取工程所有资源文件
     */
    protected void processProperties(
            ConfigurableListableBeanFactory beanFactory, Properties props) {
        try {
            List<String> list = new ArrayList<String>();
            list.add("jdbc.username");
            list.add("jdbc.password");
            list.add("jdbc.url");
            decryptProperty(list, props);
        } catch (Exception e) {
            log.info("加密配置解密失败！");
            e.printStackTrace();
        }
        super.processProperties(beanFactory, props);
        propertiesMap = new HashMap<String, String>();
        Object key = null;
        String keyStr = null, value = null;
        for (Iterator<Object> localIterator = props.keySet().iterator(); localIterator
                .hasNext(); ) {
            key = localIterator.next();
            keyStr = key.toString();
            value = props.getProperty(keyStr, "");
            String encoding = StringUtils.getEncoding(value);
            try {
                value = new String(value.getBytes(encoding), this.encoding);
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            propertiesMap.put(keyStr, value);
        }
    }

    /**
     * 相关加密资源值解密
     *
     * @param list  需要解密的资源自key列表
     * @param props 资源文件对象
     */
    private void decryptProperty(List<String> list, Properties props) {
        try {
            String modulus = props.getProperty("modulus");
            String private_exponent = props.getProperty("private_exponent");
            RSAPrivateKey priKey = RSAUtils.getPrivateKey(modulus,
                    private_exponent);
            for (String key : list) {
                String mi_value = props.getProperty(key);
                String ming_value = RSAUtils.decryptByPrivateKey(mi_value,
                        priKey);
                props.setProperty(key, ming_value);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取所有资源值配置信息
     *
     * @return
     */
    public static Map<String, String> getPropertiesMap() {
        return propertiesMap;
    }

    /**
     * 获取字符串资源值
     *
     * @param key 资源值key
     * @return
     */
    public static String getStringProperty(String key) {
        return propertiesMap.get(key);
    }

    /**
     * 获取字符串资源值
     *
     * @param key          资源值key
     * @param defaultValue 若未设置则返回此默认值
     * @return
     */
    public static String getStringProperty(String key, String defaultValue) {
        String propertyValue = propertiesMap.get(key);
        if (propertyValue == null) {
            return defaultValue;
        }
        return propertyValue;
    }

    /**
     * 获取字符串资源值
     *
     * @param key 资源值key
     * @return
     */
    public static Boolean getBooleanProperty(String key) {
        return getBooleanProperty(key, null);
    }

    /**
     * 获取字符串资源值
     *
     * @param key          资源值key
     * @param defaultValue 若未设置则返回此默认值
     * @return
     */
    public static Boolean getBooleanProperty(String key, Boolean defaultValue) {
        String propertyValue = propertiesMap.get(key);
        if (propertyValue == null) {
            return BooleanUtils.toBooleanObject(defaultValue);
        }
        return BooleanUtils.toBooleanObject(propertyValue);
    }

    /**
     * 获取整型资源值
     *
     * @param key          资源值key
     * @param defaultValue 若未设置或设置值类型错误则返回此默认值
     * @return
     */
    public static Integer getIntegerProperty(String key, Integer defaultValue) {
        String propertyValue = getStringProperty(key);
        try {
            if (propertyValue != null) {
                return Integer.parseInt(propertyValue);
            }
        } catch (NumberFormatException e) {
            log.info("资源值：" + key + "数据类型设置错误!");
            e.printStackTrace();
        }
        return defaultValue;
    }

    /**
     * 获取整型资源值
     *
     * @param key          资源值key
     * @param defaultValue 若未设置或设置值类型错误则返回此默认值
     * @return
     */
    public static Long getLongProperty(String key, Long defaultValue) {
        String propertyValue = getStringProperty(key);
        if (propertyValue != null) {
            try {
                return Long.parseLong(propertyValue);
            } catch (NumberFormatException e) {
                log.info("资源值：" + key + "数据类型设置错误!");
                e.printStackTrace();
            }
        }
        return defaultValue;
    }

    /**
     * 获取单精度资源值
     *
     * @param key          资源值key
     * @param defaultValue 若未设置或设置值类型错误则返回此默认值
     * @return
     */
    public static Float getFloatProperty(String key, Float defaultValue) {
        String propertyValue = getStringProperty(key);
        if (propertyValue != null) {
            try {
                return Float.parseFloat(propertyValue);
            } catch (NumberFormatException e) {
                log.info("资源值：" + key + "数据类型设置错误!");
                e.printStackTrace();
            }
        }
        return defaultValue;
    }

    /**
     * 获取双精度资源值
     *
     * @param key          资源值key
     * @param defaultValue 若未设置或设置值类型错误则返回此默认值
     * @return
     */
    public static Double getDoubleProperty(String key, Double defaultValue) {
        String propertyValue = getStringProperty(key);
        if (propertyValue != null) {
            try {
                return Double.parseDouble(propertyValue);
            } catch (NumberFormatException e) {
                log.info("资源值：" + key + "数据类型设置错误!");
                e.printStackTrace();
            }
        }
        return defaultValue;
    }

    public static String getEncoding(String str) {
        String encode = "GB2312";
        try {
            if (str.equals(new String(str.getBytes(encode), encode))) {
                String s = encode;
                return s;
            }
        } catch (Exception exception) {
        }
        encode = "ISO-8859-1";
        try {
            if (str.equals(new String(str.getBytes(encode), encode))) {
                String s1 = encode;
                return s1;
            }
        } catch (Exception exception1) {
        }
        encode = "UTF-8";
        try {
            if (str.equals(new String(str.getBytes(encode), encode))) {
                String s2 = encode;
                return s2;
            }
        } catch (Exception exception2) {
        }
        encode = "GBK";
        try {
            if (str.equals(new String(str.getBytes(encode), encode))) {
                String s3 = encode;
                return s3;
            }
        } catch (Exception exception3) {
        }
        return "";
    }
}